﻿using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Sencha.Direct;

namespace System.Web.Mvc
{
    public static class RouterHelpers
    {
        private const string DefaultUrl = "Router/{action}";
        private static readonly RouteValueDictionary DefaultRouteDefaults;
        internal static readonly Route DefaultRoute;

        static RouterHelpers()
        {
            DefaultRouteDefaults = new RouteValueDictionary { { "controller", "Router" }, { "action", "Index" } };

            var route = new Route(
                url: DefaultUrl,
                defaults: DefaultRouteDefaults,
                constraints: null,
                dataTokens: null,
                routeHandler: new StopRoutingHandler()
            );
        }

        private class RouterImpl : Router { }
        private class RouteHandler<RouterT> : IRouteHandler where RouterT : Router, new()
        {
            public IHttpHandler GetHttpHandler(RequestContext requestContext)
            {
                var router = new RouterT();
                router.ControllerContext = new System.Web.Mvc.ControllerContext(requestContext, router);
				router.Url = new UrlHelper(requestContext);
                return router;
            }
        }

		public static void RegisterDirectRouter(this RouteCollection routes)
        {
            RouterHelpers.RegisterDirectRouter<RouterImpl>(routes);
        }
		public static void RegisterDirectRouter<RouterT>(this RouteCollection routes) where RouterT : Router, new()
        {
            if (routes == null)
                throw new NullReferenceException();

            var route = new Route(
                url: DefaultUrl,
                defaults: DefaultRouteDefaults,
                constraints: null,
                dataTokens: null,
                routeHandler: new RouteHandler<RouterT>());
            routes.Add(route);
        }

		public static void RegisterDirectRouter(this AreaRegistrationContext context)
        {
			RouterHelpers.RegisterDirectRouter<RouterImpl>(context);
        }
        public static void RegisterDirectRouter<RouterT>(this AreaRegistrationContext context) where RouterT : Router, new()
        {
            if (context == null)
                throw new NullReferenceException();

            var tokens = new RouteValueDictionary { { "area", context.AreaName } };

            var route = new Route(
                url: context.AreaName + "/" + DefaultUrl,
                defaults: DefaultRouteDefaults,
                constraints: null,
                dataTokens: tokens,
                routeHandler: new RouteHandler<RouterT>());

            context.Routes.Add(route);
        }
    }
}
